#ifndef __MY_THREADPOOL__
#define __MY_THREADPOOL__
#include <pthread.h>
#include <vector>
#include <queue>
#include <unordered_map>
#include <string>
#include "Hot.hpp"
#include <functional>
using namespace std;
static int DefaultThreadMax = 5;
using Task = function<void(Cloud::BackupInfo &info, string &realpath)>;
namespace Cloud
{
    struct ThreadInfo
    {
        pthread_t tid;
        std::string threadname;
    };

    class ThreadPool
    {
    private:
        Task _callback;
        pthread_mutex_t _mutex;
        pthread_cond_t _cond;
        vector<ThreadInfo> _threads;                       // 存放线程
        queue<pair<Cloud::BackupInfo &, string &>> _tasks; // 存放任务数据
                                                           // vector<Task> _tasks;

    public:
        ThreadPool(Task callback, int num = DefaultThreadMax) : _callback(callback), _threads(num)
        {
            pthread_mutex_init(&_mutex, nullptr);
            pthread_cond_init(&_cond, nullptr);
        }

        void addTask(Cloud::BackupInfo &info, string &realpath)
        {
            pthread_mutex_lock(&_mutex);
            _tasks.push({info, realpath});
            pthread_cond_broadcast(&_cond); // 唤醒消费线程
            pthread_mutex_unlock(&_mutex);
            sleep(1);
        }

        static void *Routine(void *args)
        {
            while (true)
            {
                ThreadPool *th = static_cast<ThreadPool *>(args);
                pthread_mutex_lock(&(th->_mutex));
                while (th->_tasks.empty()) // 防止伪唤醒线程
                {
                    pthread_cond_wait(&(th->_cond), &(th->_mutex));
                }
                DEBUG("%s%d", "Tread_TaskQueue Remaining Quantity :", th->_tasks.size());
                auto ret = th->_tasks.front();
                th->_tasks.pop();
                pthread_mutex_unlock(&(th->_mutex));
                DEBUG("%s%lu", "Tread is Running,ThreadId: ", pthread_self());
                th->_callback(ret.first, ret.second);
            }
        }
        void Start()
        {
            for (int i = 0; i < _threads.size(); i++)
            {
                ThreadInfo Info;
                Info.threadname = "thread-" + to_string(i + 1);
                pthread_create(&(_threads[i].tid), nullptr, Routine, this);
            }
            DEBUG("%s%d", "ThreadPool is started,thread nums is ", DefaultThreadMax);
        }
        ~ThreadPool()
        {
            for (auto &thread : _threads)
            {
                pthread_join(thread.tid, nullptr); // 等待线程结束
            }
            pthread_mutex_destroy(&_mutex);
            pthread_cond_destroy(&_cond);
            WARN("%s", "ThreadPool is Distroyed!");
        }
    };
}

#endif